package com.delu.mq;

import com.alibaba.fastjson.JSONObject;
import com.delu.data.Result;
import com.delu.dto.OrderPayDTO;
import com.delu.dto.PayRanDTO;
import com.delu.dto.TravelOrderDTO;
import com.delu.dto.UserPhonDTO;
import com.delu.entity.PayRank;
import com.delu.entity.TravelOrder;
import com.delu.feign.MessageFegin;
import com.delu.feign.OrderFegin;
import com.delu.feign.PayRankFegin;
import com.delu.feign.UserFeign;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;

/**
 * Created by zhangpk on 2021/12/21
 **/
@Component
@RocketMQMessageListener(topic = "order-pay-topic",consumerGroup = "order-payment")
public class RocketMQConsumeOrder implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private PayRankFegin payRankFegin;
    @Autowired
    private OrderFegin orderFegin;
    @Autowired
    private MessageFegin messageFegin;
    @Autowired
    private UserFeign userFeign;

    public static final String ORDER_KEY = "order";

    @Override
    public void onMessage(String message) {
        System.out.println("消息接收成功" + message);
    }

    //手动接管ACK机制,如果消费失败,mq会重试 :默认16次 , 时间间隔越来越长,重试次数越来越多(消费成功的可能性越来越小)
    @Override
    public void prepareStart(DefaultMQPushConsumer consumer) {
        consumer.registerMessageListener(new MessageListenerConcurrently() {
            @Override
            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> list,
                                                            ConsumeConcurrentlyContext consumeConcurrentlyContext) {
                MessageExt message = list.get(0);
                message.getBody();//获取消息实体类,这个时候不支持直接接收对象
                message.getMsgId();//消息的id,通过此id我们结合redis可以保证消费幂等性
                message.getReconsumeTimes();//消息重试的次数
                try{
                    TravelOrder order = new TravelOrder();
                    TravelOrderDTO orderDTO = new TravelOrderDTO();
                    PayRanDTO payRanDTO = new PayRanDTO();
                    String messageBody = new String(message.getBody(), "utf-8");
                    PayRank payRank = new PayRank();
                    OrderPayDTO orderPayDTO = JSONObject.parseObject(messageBody, OrderPayDTO.class);
                    //根据订单号查询该订单信息

                    //判断该状态是付款还是退款还是交易完成
                    if(orderPayDTO.getOrderStatus() == 3){
                        OrderPayDTO o = (OrderPayDTO)redisTemplate.boundValueOps(ORDER_KEY + orderPayDTO.getOrderId()).get();
                        //判断是支付还是续费   根据缓存中的订单号为key  判断是否有该key  value是续费时间
                        if(redisTemplate.hasKey(ORDER_KEY + o.getNewOrderId())){
                            Result<TravelOrderDTO> result = orderFegin.selectPayRank(o.getOrderId());
                            TravelOrderDTO dto = result.getData();
                            BeanUtils.copyProperties(dto,order);
                            //存在  续费  调用订单修改接口
                            order.setOrderStatus(orderPayDTO.getOrderStatus());
                            order.setEndTime(o.getDate());
                            BeanUtils.copyProperties(order,dto);
                            orderFegin.updateTravelOrderById(dto);
                            //消费记录
                            payRank.setConsumerMoney(order.getOrderMount());

                            payRank.setConsumerTime(LocalDateTime.now());
                            payRank.setUserId(order.getUserId());
                            payRank.setStatus(1);//消费
                            payRank.setSerialNum(orderPayDTO.getSerialNum());
                            BeanUtils.copyProperties(payRank,payRanDTO);
                            payRankFegin.insertCarBrand(payRanDTO);
                            //修改完成  给用户发送短信   调用短信接口
                            Result result1 = userFeign.selectUserById(order.getUserId());
                            UserPhonDTO userPhonDTO = (UserPhonDTO)result1.getData();
                            messageFegin.sends(userPhonDTO.getPhone(),"续费成功");
                            //删除redis key
                            redisTemplate.delete(ORDER_KEY+orderPayDTO.getOrderId());
                        }else {
                            //如果不存在 就是用户第一次支付该订单
                            Result<TravelOrderDTO> result = orderFegin.selectPayRank(o.getOrderId());
                            TravelOrderDTO dto = result.getData();
                            BeanUtils.copyProperties(dto,order);
                            //调用订单修改接口
                            order.setOrderStatus(orderPayDTO.getOrderStatus());
                            BeanUtils.copyProperties(order,dto);
                            orderFegin.updateTravelOrderById(dto);
                            //添加消费记录
                            payRank.setConsumerMoney(order.getOrderMount());
                            payRank.setConsumerTime(LocalDateTime.now());
                            payRank.setUserId(order.getUserId());
                            payRank.setStatus(1);//消费
                            payRank.setSerialNum(orderPayDTO.getSerialNum());
                            BeanUtils.copyProperties(payRank,payRanDTO);
                            payRankFegin.insertCarBrand(payRanDTO);
                            //修改完成  给用户发送短信   调用短信接口
                            Result result1 = userFeign.selectUserById(order.getUserId());
                            UserPhonDTO userPhonDTO = (UserPhonDTO) result1.getData();
                            messageFegin.sends(userPhonDTO.getPhone(), "付款成功");
                        }
                    }else if(orderPayDTO.getOrderStatus() == 2){
                        //退款业务 修改订单状态
                        Result<TravelOrderDTO> result = orderFegin.selectPayRank(orderPayDTO.getOrderId());
                        TravelOrderDTO dto = result.getData();
                        BeanUtils.copyProperties(dto,order);
                        order.setOrderStatus(orderPayDTO.getOrderStatus());
                        BeanUtils.copyProperties(order,dto);
                        orderFegin.updateTravelOrderById(dto);
                        //给用户发送短信
                        payRank.setRefundMoney(order.getOrderMount());
                        payRank.setRefundTime(LocalDateTime.now());
                        payRank.setUserId(order.getUserId());
                        payRank.setStatus(2);//退款
                        payRank.setSerialNum(orderPayDTO.getSerialNum());
                        BeanUtils.copyProperties(payRank,payRanDTO);
                        payRankFegin.insertCarBrand(payRanDTO);
                        //修改完成  给用户发送短信   调用短信接口
                        Result result1 = userFeign.selectUserById(order.getUserId());
                        UserPhonDTO userPhonDTO = (UserPhonDTO)result1.getData();
                        messageFegin.sends(userPhonDTO.getPhone(),"退款成功");
                    }else if(orderPayDTO.getOrderStatus() == 7){
                        //交易关闭 修改订单状态
                        Result<TravelOrderDTO> result = orderFegin.selectPayRank(orderPayDTO.getOrderId());
                        TravelOrderDTO dto = result.getData();
                        BeanUtils.copyProperties(dto,order);
                        order.setOrderStatus(orderPayDTO.getOrderStatus());
                        BeanUtils.copyProperties(order,dto);
                        orderFegin.updateTravelOrderById(dto);
                    }
                    System.out.println("ACK消息消费成功!!!" + messageBody);
                }catch (Exception e){
//                    e.printStackTrace();
                    System.out.println("消息消费失败,请稍后重试");
                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
                }
                return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
            }
        });
    }
}
